package com.sisgesbyte.services.proyeccion;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.inject.Inject;

import com.sisgesbyte.common.ConstModAdministracion;
import com.sisgesbyte.common.ConstProyeccion;
import com.sisgesbyte.common.ConstantesInternasSistema;
import com.sisgesbyte.common.Validaciones;
import com.sisgesbyte.dao.beanDao.FiltrosBean;
import com.sisgesbyte.dao.beanDao.FiltrosSQLBean;
import com.sisgesbyte.dao.beanDao.ProyeccionClienteDetalleResponse;
import com.sisgesbyte.dao.proyeccion.MantProyeccionClienteDetalleDao;
import com.sisgesbyte.data.entity.comun.GenericEntity;
import com.sisgesbyte.data.entity.proyeccion.ProyeccionClienteDetalleEntity;
import com.sisgesbyte.services.commonBean.GenericGuardarResponse;
import com.sisgesbyte.services.commonBean.GenericResponse;
import com.sisgesbyte.services.proyeccion.bean.FiltroProyClienteBean;
import com.sisgesbyte.services.proyeccion.bean.ListaProyeccionClienteBean;
import com.sisgesbyte.services.proyeccion.bean.ListaProyeccionClienteDetalleBean;
import com.sisgesbyte.services.proyeccion.bean.ListaProyeccionClienteDetalleResponse;
import com.sisgesbyte.services.proyeccion.bean.ListaProyeccionClienteResponse;

@Stateless
public class MantProyeccionClienteDetalleServiceImpl implements
		MantProyeccionClienteDetalleService {

	@EJB
	private MantProyeccionClienteDetalleDao mantProyeccionClienteDetalleDao;
	@EJB
	private MantProyeccionClienteService mantProyeccionClienteService;
	@Inject
	private Validaciones validaciones;
	
	@Override
	public ListaProyeccionClienteDetalleResponse mostrarProyeccionClienteDetalle(
			String codTransaccion, FiltroProyClienteBean filtroOpciones) {
		String mensajeTransaccionMetodo = "[mostrarProyeccionClienteDetalle idTx=" + codTransaccion + "] - ";
		ListaProyeccionClienteDetalleResponse response = new ListaProyeccionClienteDetalleResponse();
		
		List<ProyeccionClienteDetalleEntity> listaProyeccionClientes = null;
		try{
			FiltrosSQLBean filtroSQL = new FiltrosSQLBean();
			List<Object> valores = new ArrayList<>();
			List<FiltrosBean> filtro = new ArrayList<FiltrosBean>();

			if(filtroOpciones.getIdCliente() > 0){
				FiltrosBean listaCliente = new FiltrosBean();
				List<String> campoCliente = new ArrayList<String>();
				campoCliente.add("pc.cliente_id");
				listaCliente.setCampos(campoCliente);
				listaCliente.setOperador("=");
				filtro.add(listaCliente);
				valores.add(filtroOpciones.getIdCliente());
			}
			
			if(filtroOpciones.getIdLocalCliente() > 0){
				FiltrosBean listaLocal = new FiltrosBean();
				List<String> campoLocal = new ArrayList<String>();
				campoLocal.add("pc.cliente_local_id");
				listaLocal.setCampos(campoLocal);
				listaLocal.setOperador("=");
				filtro.add(listaLocal);
				valores.add(filtroOpciones.getIdLocalCliente());
			}
			if(filtroOpciones.getIdPeriodo() > 0){
				FiltrosBean listaPeriodo = new FiltrosBean();
				List<String> campoPeriodo = new ArrayList<String>();
				campoPeriodo.add("pc.periodo_id");
				listaPeriodo.setCampos(campoPeriodo);
				listaPeriodo.setOperador("=");
				filtro.add(listaPeriodo);
				valores.add(filtroOpciones.getIdPeriodo());
			}
			if(filtroOpciones.getTxtBuscar() !=null){
				if(filtroOpciones.getTxtBuscar().trim().length() > 0){
					// filtro por String
						FiltrosBean listaCampo = new FiltrosBean();
						List<String> campo = new ArrayList<String>();
						campo.add("pcd.id");
						campo.add("m.marca");
						campo.add("p.cod_prod");
						campo.add("p.producto");
						campo.add("cp.nombre");
						listaCampo.setCampos(campo);
						listaCampo.setOperador("like");
						filtro.add(listaCampo);
						valores.add("%" + filtroOpciones.getTxtBuscar() + "%");
				}
					// -------------------
			}

			filtroSQL.setListaFiltros(filtro);
			filtroSQL.setListaValores(valores);
			listaProyeccionClientes = mantProyeccionClienteDetalleDao.proyeccionClienteDetalle(filtroSQL); 
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al listar de  BD " + e);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
			return response;
		}
		
		if(listaProyeccionClientes.size() > 0){
			List<ListaProyeccionClienteDetalleBean> listaProyeccionCliente = new ArrayList<ListaProyeccionClienteDetalleBean>();
			
			for(ProyeccionClienteDetalleEntity ls : listaProyeccionClientes){
				ListaProyeccionClienteDetalleBean bean = new ListaProyeccionClienteDetalleBean();
					bean.setCantidadProyectada(ls.getCantidad_proyectada());
					bean.setCategoriaProducto(validaciones.validarCamposString(ls.getCategoria_producto()));
					bean.setCategoriaProductoId(ls.getCategoria_producto_id());
					bean.setClienteId(ls.getCliente_id());
					bean.setClienteLocalId(ls.getCliente_local_id());
					bean.setCodigoBanda(validaciones.validarCamposString(ls.getCodigo_banda()));
					bean.setCodLocal(validaciones.validarCamposString(ls.getCod_local()));
					bean.setNumDoc(validaciones.validarCamposString(ls.getNum_doc()));
					bean.setTipoIdentificacionId(ls.getTipo_identificacion_id());
					bean.setRazonSocial(validaciones.validarCamposString(ls.getRazon_social()));
					bean.setNombre(validaciones.validarCamposString(ls.getNombre()));
					bean.setApellido(validaciones.validarCamposString(ls.getApellido()));
					bean.setZonaId(ls.getZona_id());
					bean.setCanalId(ls.getCanal_id());
					bean.setCodProd(validaciones.validarCamposString(ls.getCod_prod()));
					bean.setId(ls.getId());
					bean.setMarca(validaciones.validarCamposString(ls.getMarca()));
					bean.setMarcaId(ls.getMarca_id());
					bean.setPeriodoId(ls.getPeriodo_id());
					bean.setProducto(validaciones.validarCamposString(ls.getProducto()));
					bean.setProductoId(ls.getProducto_id());
					bean.setProyeccionClienteId(ls.getProyeccion_cliente_id());
					bean.setPrecioPromedio(ls.getPrecio_promedio());
				listaProyeccionCliente.add(bean);
			}
			response.setIdTransaccion(codTransaccion);
			response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
			response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
			response.setListaClienteDetalle(listaProyeccionCliente);;
		
		} else {
			response.setIdTransaccion(codTransaccion);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDF);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDF);
		}

		return response;
	}

	@Override
	public GenericResponse nuevaProyeccioClienteDetalle(String codTransaccion,
			ListaProyeccionClienteDetalleBean request) {
		String mensajeTransaccionMetodo = "[nuevaProyeccioClienteDetalle idTx=" + codTransaccion + "] - ";
		GenericResponse response = new GenericResponse();
		
		boolean existe = false;
		int idProyeccionCliente =0;
		
		try{
			FiltroProyClienteBean filtroOpciones = new FiltroProyClienteBean();
			filtroOpciones.setIdCliente(request.getClienteId());
			filtroOpciones.setIdLocalCliente(request.getClienteLocalId());
			filtroOpciones.setIdPeriodo(request.getPeriodoId());
			filtroOpciones.setTxtBuscar("");
			//1.- verificamos si existe la proyeccion del cliente por monto
			ListaProyeccionClienteResponse listaProyeccionCliente = mantProyeccionClienteService.mostrarProyeccionCLiente(codTransaccion, filtroOpciones);
		
			if(listaProyeccionCliente.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
				existe=true;
				for(ListaProyeccionClienteBean ls :listaProyeccionCliente.getListaProyeccionCliente()){
					idProyeccionCliente = ls.getId();
				}
			}
			
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al obtener la Proyeccion en BD " + e);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT);
			return response;
		}
		if(!existe){
			//2.- creamos la proyeccion por monto para obtener el id
			try{
				ListaProyeccionClienteBean req = new ListaProyeccionClienteBean();
				req.setClienteId(request.getClienteId());
				req.setClienteLocalId(request.getClienteLocalId());
				req.setCodigoBanda("");
				req.setPeriodoId(request.getPeriodoId());
				req.setMontoProyectada(BigDecimal.ZERO);
				GenericGuardarResponse nuevoProy = mantProyeccionClienteService.nuevaProyeccionCLiente(codTransaccion, req);
				if(nuevoProy.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
					idProyeccionCliente = Integer.valueOf(nuevoProy.getCodigoSaved());
				}else{
					System.out.println("Error Funcional al tratar de registrar monto proyeccion ffvv");
					response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDF);
					response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDF);
					return response;
				}
			}catch(Exception e){
				System.out.println(mensajeTransaccionMetodo + "Hubo un error al registrar la Proyeccion en BD " + e);
				response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
				response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT);
				return response;
			}
		}
		
		try{
			ProyeccionClienteDetalleResponse req = new ProyeccionClienteDetalleResponse();
			req.setCantidadProyectada(request.getCantidadProyectada());
			req.setCodigoBanda(validaciones.validarCamposString(request.getCodigoBanda()));
			req.setProductoId(request.getProductoId());
			req.setProyeccionClienteId(idProyeccionCliente);
			//3.- registramos la proyeccion 
			GenericEntity nuevaProy = mantProyeccionClienteDetalleDao.guardarProyeccionClienteDetalle(req);
			
			if(nuevaProy.getCod_error() == Integer.valueOf(ConstantesInternasSistema.CODIGO_EXITO)){
				//4.- obtemos la suma de la proyeccion de acuerdo al filtro
				BigDecimal totalProyeccion = null;
				try{
					FiltroProyClienteBean filtro = new FiltroProyClienteBean();
					filtro.setIdCliente(request.getClienteId());
					filtro.setIdLocalCliente(request.getClienteLocalId());
					filtro.setIdPeriodo(request.getPeriodoId());
					filtro.setTxtBuscar("");
					totalProyeccion =  montoTotalProyeccion(codTransaccion, filtro);
				}catch(Exception e){
					System.out.println(mensajeTransaccionMetodo + "Error al obtener la suma de la proyeccion del canal detalle " + e);
					response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
					response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
					return response;
				}
				
				//5.- actualizamos la proyeccion total del canal 
				
				try{
					
					ListaProyeccionClienteBean reqCanal = new ListaProyeccionClienteBean();
					reqCanal.setClienteId(request.getClienteId());
					reqCanal.setClienteLocalId(request.getClienteLocalId());
					reqCanal.setCodigoBanda("");
					reqCanal.setId(idProyeccionCliente);
					reqCanal.setMontoProyectada(totalProyeccion);
					reqCanal.setPeriodoId(request.getPeriodoId());
					
					GenericResponse actualizarProyCliente = mantProyeccionClienteService.editarProyeccionCLiente(codTransaccion, reqCanal);
					
					if(actualizarProyCliente.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
						System.out.println("Se registro correctamente la proyeccion ");
						response.setIdTransaccion(codTransaccion);
						response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
						response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
					}else{
						System.out.println("IDF: Hubo un error al actualizar el monto de la proyeccion del canal");
						response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDF);
						response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDF);
					}
					
				}catch(Exception e){
					System.out.println(mensajeTransaccionMetodo + "Hubo un error al actualizar el monto de la proyeccion del canal " + e);
					response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
					response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT);
					return response;
				}
			}else{
				response.setCodigoRespuesta(String.valueOf(nuevaProy.getCod_error()));
				response.setMensajeRespuesta(nuevaProy.getMsj_error());
			}
			
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al registrar la Proyeccion en BD " + e);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT);
		}
		
		return response;
	}

	@Override
	public GenericResponse editarProyeccionClienteDetalle(
			String codTransaccion, ListaProyeccionClienteDetalleBean request) {
		String mensajeTransaccionMetodo = "[editarProyeccionClienteDetalle idTx=" + codTransaccion + "] - ";
		GenericResponse response = new GenericResponse();
		
		try{
			ProyeccionClienteDetalleResponse req = new ProyeccionClienteDetalleResponse();
			req.setId(request.getId());
			req.setCantidadProyectada(request.getCantidadProyectada());
			req.setCodigoBanda(validaciones.validarCamposString(request.getCodigoBanda()));
			req.setProductoId(request.getProductoId());
			req.setProyeccionClienteId(request.getProyeccionClienteId());
			
			GenericEntity nuevaProy = mantProyeccionClienteDetalleDao.actualizarProyeccionClienteDetalle(req);
			
			if(nuevaProy.getCod_error() == Integer.valueOf(ConstantesInternasSistema.CODIGO_EXITO)){
				//1.- obtemos la suma de la proyeccion de acuerdo al filtro
				BigDecimal totalProyeccion = null;
				try{
					FiltroProyClienteBean filtro = new FiltroProyClienteBean();
					filtro.setIdCliente(request.getClienteId());
					filtro.setIdLocalCliente(request.getClienteLocalId());
					filtro.setIdPeriodo(request.getPeriodoId());
					filtro.setTxtBuscar("");
					totalProyeccion =  montoTotalProyeccion(codTransaccion, filtro);
				}catch(Exception e){
					System.out.println(mensajeTransaccionMetodo + "Error al obtener la suma de la proyeccion del canal detalle " + e);
					response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
					response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
					return response;
				}
				
				//2.- actualizamos la proyeccion total del canal 
				
				try{
					ListaProyeccionClienteBean reqCanal = new ListaProyeccionClienteBean();
					reqCanal.setClienteId(request.getClienteId());
					reqCanal.setClienteLocalId(request.getClienteLocalId());
					reqCanal.setCodigoBanda("");
					reqCanal.setId(request.getId());
					reqCanal.setMontoProyectada(totalProyeccion);
					reqCanal.setPeriodoId(request.getPeriodoId());
					
					GenericResponse actualizarProyCliente = mantProyeccionClienteService.editarProyeccionCLiente(codTransaccion, reqCanal);
					
					if(actualizarProyCliente.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
						System.out.println("Se registro correctamente la proyeccion ");
						response.setIdTransaccion(codTransaccion);
						response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
						response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
					}else{
						System.out.println("IDF: Hubo un error al actualizar el monto de la proyeccion del cliente");
						response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDF);
						response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDF);
					}
					
				}catch(Exception e){
					System.out.println(mensajeTransaccionMetodo + "Hubo un error al actualizar el monto de la proyeccion del canal " + e);
					response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
					response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT);
					return response;
				}
			}else{
				response.setCodigoRespuesta(String.valueOf(nuevaProy.getCod_error()));
				response.setMensajeRespuesta(nuevaProy.getMsj_error());
			}
			
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al registrar la Proyeccion en BD " + e);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT);
		}
		
		return response;
	}

	@Override
	public GenericResponse deleteProyeccionClienteDetalle(
			String codTransaccion, ListaProyeccionClienteDetalleBean request) {
		String mensajeTransaccionMetodo = "[deleteProyeccionClienteDetalle idTx=" + codTransaccion + "] - ";
		GenericResponse response = new GenericResponse();
		
		try{
			//1.- eliminamos Proy cliente
			GenericEntity nuevaProy = mantProyeccionClienteDetalleDao.eliminarProyeccionClienteDetalle(request.getId());
			
			if(nuevaProy.getCod_error() == Integer.valueOf(ConstantesInternasSistema.CODIGO_EXITO)){
				//2.- obtemos la suma de la proyeccion de acuerdo al filtro
				BigDecimal totalProyeccion = null;
				try{
					FiltroProyClienteBean filtro = new FiltroProyClienteBean();
					filtro.setIdCliente(request.getClienteId());
					filtro.setIdLocalCliente(request.getClienteLocalId());
					filtro.setIdPeriodo(request.getPeriodoId());
					filtro.setTxtBuscar("");
					totalProyeccion =  montoTotalProyeccion(codTransaccion, filtro);
				}catch(Exception e){
					System.out.println(mensajeTransaccionMetodo + "Error al obtener la suma de la proyeccion del canal detalle " + e);
					response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
					response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
					return response;
				}
				
				//3.- actualizamos la proyeccion total del canal 
				
				try{
					ListaProyeccionClienteBean reqCanal = new ListaProyeccionClienteBean();
					reqCanal.setClienteId(request.getClienteId());
					reqCanal.setClienteLocalId(request.getClienteLocalId());
					reqCanal.setCodigoBanda("");
					reqCanal.setId(request.getId());
					reqCanal.setMontoProyectada(totalProyeccion);
					reqCanal.setPeriodoId(request.getPeriodoId());
					
					GenericResponse actualizarProyCliente = mantProyeccionClienteService.editarProyeccionCLiente(codTransaccion, reqCanal);
					
					if(actualizarProyCliente.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
						System.out.println("Se registro correctamente la proyeccion ");
						response.setIdTransaccion(codTransaccion);
						response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
						response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
					}else{
						System.out.println("IDF: Hubo un error al actualizar el monto de la proyeccion del canal");
						response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDF);
						response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDF);
					}
					
				}catch(Exception e){
					System.out.println(mensajeTransaccionMetodo + "Hubo un error al actualizar el monto de la proyeccion del canal " + e);
					response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
					response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT);
					return response;
				}
			}else{
				response.setCodigoRespuesta(String.valueOf(nuevaProy.getCod_error()));
				response.setMensajeRespuesta(nuevaProy.getMsj_error());
			}
			
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al registrar la Proyeccion en BD " + e);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT);
		}
		
		return response;
	}
	public BigDecimal montoTotalProyeccion(String codTransaccion, FiltroProyClienteBean filtroBean){
		String mensajeTransaccionMetodo = "[montoTotalProyeccion idTx=" + codTransaccion + "] - ";
		BigDecimal monto = BigDecimal.ZERO;
		
		try{
			ListaProyeccionClienteDetalleResponse response =mostrarProyeccionClienteDetalle( codTransaccion, filtroBean);
			
			if(response.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
				for(ListaProyeccionClienteDetalleBean ls : response.getListaClienteDetalle()){
					monto = monto.add(ls.getCantidadProyectada().multiply(ls.getPrecioPromedio()));
				}
			}
			
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Error al obtener el monto de la proyeccio " + e);
			monto = BigDecimal.ZERO;
		}
		
		return monto;
	}
}
